package com.cuiweiyou.uiautomator20;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Rect;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.StaleObjectException;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * www.gaohaiyan.com
 */
public class TestUtilChat {
    private TestUtilChat() {
    }

    /**
     * 在此方法内执行点击<br/>
     * 进入此好友的聊天界面<br/>
     * 查找对方的消息<br/>
     * 回复消息<br/>
     * 回复结束后停留在此好友的聊天页面内
     *
     * @param context          应用上下文
     * @param clipboardManager 粘贴板
     * @param device           设备驱动器
     * @param item             发生点击的控件
     * @param tip              提示
     * @param isKeep           是否为保留聊天列表模式
     *                         <br/>
     * @return 对方信息数组：<br/>
     * result[0] = phone;<br/>
     * result[1] = wxid;<br/>
     * result[2] = notename;<br/>
     * result[3] = nickname;
     */
    public static String[] doChatting(Context context, ClipboardManager clipboardManager, UiDevice device, UiObject2 item, String tip, boolean isKeep) {
        String nameSplitFlag = "<<>>";
        item.click();
        UtilLogs.saveLog("点击了item");

        // nextAty，进入聊天页面

        UtilLogs.saveLog("进入聊天页面");

        UiObject2 titleObject;

        String chat_title = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_title);
        if (null == chat_title) {
            device.wait(Until.hasObject(By.res("com.tencent.mm", "j7")), 5000); // 头部，好友的称谓
            titleObject = device.findObject(By.res("com.tencent.mm", "j7"));
            UtilLogs.saveLog("查找好友聊天页面标题 j7");
        } else {
            String id = chat_title.replace("com.tencent.mm:id/", "");
            device.wait(Until.hasObject(By.res("com.tencent.mm", id)), 5000);
            titleObject = device.findObject(By.res("com.tencent.mm", id));
            UtilLogs.saveLog("查找好友聊天页面标题 id=" + id);
        }

        TestUtilCtrl.showCurrentActivity(device, "是否为'好友聊天'"); // 聊天页

        String phone = "";
        String notename = "";
        String wxid = "";
        String nickname = "";

        String title = titleObject.getText();
        if (title.contains(nameSplitFlag)) {
            String[] split = title.split(nameSplitFlag);
            phone = split[0];
            notename = split[1];
        } else {
            notename = title;
        }
        UtilLogs.saveLog("好友wxid：" + wxid);
        UtilLogs.saveLog("好友phone：" + phone);
        UtilLogs.saveLog("好友notename：" + notename);
        UtilLogs.saveLog("好友nickname：" + nickname);

        // 现在的逻辑是回复后就删除聊天，只有好友发消息来了才能进入此item的聊天页，即一定能找到好友的avatar

        ModelFriend friend = UtilSQLite.getInstance(context).hasFriend(phone, wxid, notename, nickname, "proactive"); // 一次正常聊天中，是否要获取详细信息
        if (null != friend) {
            if (TextUtils.isEmpty(phone) && TextUtils.isEmpty(wxid)) {
                UtilLogs.saveLog("来来回回查找详细信息");
                String[] friendAvatar = TestUtilChat.getFriendAvatar(device, notename);// 从首页进入的聊天，查找好友的头像，进行点击，用以获取微信号等
                wxid = friendAvatar[0];
                notename = friendAvatar[1];
                nickname = friendAvatar[2];
            }

            UtilLogs.saveLog("保存好友入库1：" + notename);
            UtilSQLite.getInstance(context).insertFriend(phone, wxid, notename, nickname, "proactive"); //doChating 如果数据库里没有，这时就作为proactive保存
        } else {
            UtilLogs.saveLog("保存好友入库2：" + notename);
            UtilSQLite.getInstance(context).insertFriend(phone, wxid, notename, nickname, "proactive"); // doChating 第一次保存
        }

        List<String> messageList = TestUtilChat.getMessageList(context, clipboardManager, device, phone, wxid, isKeep); // 和老朋友聊天，to do 根据多条消息回复

        justQuestionAndAnswer(context, clipboardManager, device, phone, wxid, tip, isKeep, messageList); // doChating

        //Log.e("ard", "延时1秒，等待回复");

        //Moonmen开启了朋友验证，你还不是他（她）朋友。请先发送朋友验证请求，对方验证通过后，才能聊天。发送朋友验证
        //Boolean isothersidedeleted1 = device.wait(Until.hasObject(By.res("com.tencent.mm", "ani")), 2000);
        //Boolean isothersidedeleted2 = device.wait(Until.hasObject(By.textContains("开启了朋友验证，你还不是他（她）朋友。请先发送朋友验证请求")), 2000);
        //if (isothersidedeleted1 || isothersidedeleted2) { // 对方删除了我
        //    if (null != friend) {
        //        UtilSQLite.getInstance(context)
        //                  .setFriendIsDeleted(friend, true);
        //    }
        //}

        String[] result = new String[4];
        result[0] = phone;
        result[1] = wxid;
        result[2] = notename;
        result[3] = nickname;

        return result;
    }

    private static void justQuestionAndAnswer(Context context, ClipboardManager clipboardManager, UiDevice device, String phone, String wxid, String tip, boolean isKeep, List<String> messageList) {

        List<String> answerList = ManagerGimmick.getInstance().getAnswer(messageList);

        TestUtilChat.chatSayHello(context, device, phone, wxid, answerList, tip); // 查找老盆友，问好

        device.pressBack(); // 收起键盘

        messageList = TestUtilChat.getMessageList(context, clipboardManager, device, phone, wxid, isKeep);
        if (messageList.size() > 0) {
            UtilLogs.saveLog("有刚刚回复的新消息");
            justQuestionAndAnswer(context, clipboardManager, device, phone, wxid, tip, isKeep, messageList); // 可能回复很快，看看是不是有新消息
        }
    }

    /**
     * 取好友的最新信息
     *
     * @return 如果是"_+_"表示没有消息
     */
    public static List<String> getMessageList(Context context, ClipboardManager clipboardManager, UiDevice device, String phone, String wxid, boolean isKeep) {
        // 直接取文本mr控件，长文本不容易判断是左边对方的还是右边我自己的
        List<UiObject2> a6List;

        String chat_list_item = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_list_item);
        if (null == chat_list_item) {
            device.wait(Until.hasObject(By.res("com.tencent.mm", "a6")), 5000);
            a6List = device.findObjects(By.res("com.tencent.mm", "a6")); // 整行item
            UtilLogs.saveLog("查找页面内聊天记录item控件 a6");
        } else {
            String id = chat_list_item.replace("com.tencent.mm:id/", "");
            device.wait(Until.hasObject(By.res("com.tencent.mm", id)), 5000);
            a6List = device.findObjects(By.res("com.tencent.mm", id));
            UtilLogs.saveLog("查找页面内聊天记录item控件 id=" + id);
        }

        //int oy = 0;
        List<String> otherMessageList = new ArrayList<>();
        UtilLogs.saveLog("页面内聊天记录数量 " + a6List.size());
        for (int i = 0; i < a6List.size(); i++) {
            UiObject2 a6 = a6List.get(i);
            UiObject2 mp = null;
            try {

                String chat_item_avatar = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_list_item_avatar);
                if (null == chat_item_avatar) {
                    mp = a6.findObject(By.res("com.tencent.mm", "mp")); // 头像
                    UtilLogs.saveLog("查找好友头像 mp");
                } else {
                    String id = chat_item_avatar.replace("com.tencent.mm:id/", "");
                    mp = a6.findObject(By.res("com.tencent.mm", id));
                    UtilLogs.saveLog("查找好友头像 id：" + id);
                }

            } catch (StaleObjectException e) {
                e.printStackTrace();
                //UiObject2 mr = a6.findObject(By.res("com.tencent.mm", "mr")); // 重复异常
                //deleteObject(device, mr); // StaleObjectException
                StackTraceElement[] traces = e.getStackTrace();
                for (int j = 0; j < traces.length; j++) {
                    UtilLogs.saveLog("信息StaleObjectException：" + traces[j]);
                }
                UtilLogs.saveLog("查找好友头像 失败：" + e.getMessage());
                continue;
            }
            if (null == mp) {
                UtilLogs.saveLog("查找好友头像 null");
                continue;
            }
            Rect rect = mp.getVisibleBounds();
            if (rect.right < device.getDisplayWidth() / 2) {
                UtilLogs.saveLog("好友的聊天条目");
                //if (rect.top > oy) {
                //oy = rect.top;
                UiObject2 mr;
                String chat_item_msg = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_list_item_msg);
                if (null == chat_item_msg) {
                    mr = a6.findObject(By.res("com.tencent.mm", "mr")); // 文本消息View，拿不到text
                    UtilLogs.saveLog("查找消息文本控件 mr");
                } else {
                    String id = chat_item_msg.replace("com.tencent.mm:id/", "");
                    mr = a6.findObject(By.res("com.tencent.mm", id));
                    UtilLogs.saveLog("查找消息文本控件 id=" + id);
                }
                if (null != mr) {
                    String message = mr.getText();

                    if (TextUtils.isEmpty(message)) {    // 这里是个自定义View，拿不到Text，所以才靠下面的长按
                        //mr.longClick(); // 弹窗列表
                        TestUtilCtrl.longClick(device, mr);
                        UtilLogs.saveLog("长按文本控件");

                        Boolean hasCopy = device.wait(Until.hasObject(By.text("复制")), 5000);
                        if (hasCopy) {
                            UiObject2 copy = device.findObject(By.text("复制"));
                            copy.click();
                            UtilLogs.saveLog("点击了弹窗的 复制");

                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            ClipData primaryClip = clipboardManager.getPrimaryClip();
                            ClipData.Item item = primaryClip.getItemAt(0);
                            message = item.getText().toString().trim();
                            UtilLogs.saveLog("消息：" + message);

                            if (isKeep) {
                                deleteObject(device, mr); // 正常item
                            }
                        }
                    } else {
                        // message = "_+_";
                        UtilLogs.saveLog("直接拿到消息了：" + message);
                    }

                    if (!otherMessageList.contains(message)) { // 连续发了多个同样的消息
                        otherMessageList.add(message);

                        UtilLogs.saveLog("消息保存入库");
                        UtilSQLite.getInstance(context).insertChat(phone, wxid, message, "other"); // getFriendLastMessage

                        UtilLogs.saveLog("好友的聊天条目---" + message);
                    }
                } else {

                    mr = a6.findObject(By.res("com.tencent.mm", "am6")); // todo 适配图片表情-收藏表情

                    if (null != mr) {
                        String message = mr.getContentDescription();
                    } else {
                        // todo 适配 图片ImageView com.tencent.mm:id/alp 或 am6
                        // todo 适配 视频ImageView com.tencent.mm:id/alp 或 am6，播放按钮ImageView am9，时长TextView anb
                        // todo 适配 录音FrameLayout com.tencent.mm:id/anf，时长TextView com.tencent.mm:id/mr，未播放提示ImageView com.tencent.mm:id/ani
                    }
                }
                //}
            } else {
                UtilLogs.saveLog("我自己的聊天条目 略");
            }
        }

        return otherMessageList;
    }

    /**
     * 已经在聊天界面，回复若干聊天内容<br/>
     * 回复结束停留在当前聊天页面
     *
     * @param phone      好友电话
     * @param wxid       好友微信号
     * @param answerList 回复消息
     * @param tip        新好友才有的提示信息
     */
    public static void chatSayHello(Context context, UiDevice device, String phone, String wxid, List<String> answerList, String tip) {
        if (null == answerList || answerList.size() < 1) {
            UtilLogs.saveLog("回复的话术量为0");
            return;
        }

        String message = answerList.get(0);
        UtilLogs.saveLog("回复内容：" + message);
        answerList.remove(0);

        String edit_bar_txt = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_edit_bar_txt);
        String edit_bar_audio = ManagerViewID.getInstance().getSelfViewId(ManagerViewID.VIEW_ID_NAME_chat_edit_bar_audio);

        Boolean aif;
        if (null == edit_bar_txt) {
            aif = device.wait(Until.hasObject(By.res("com.tencent.mm", "aif")), 5000);
            UtilLogs.saveLog("等待输入文本框 aif");
        } else {
            String id = edit_bar_txt.replace("com.tencent.mm:id/", "");
            aif = device.wait(Until.hasObject(By.res("com.tencent.mm", id)), 5000);
            UtilLogs.saveLog("等待输入文本框 id=" + id);
        }
        while (!aif) { // 不是文本模式
            UiObject2 aid;
            if (null == edit_bar_audio) {
                aid = device.findObject(By.res("com.tencent.mm", "aid"));// 语音/文本切换按钮
                UtilLogs.saveLog("查找文本语音切换控件 aid");
            } else {
                String id = edit_bar_audio.replace("com.tencent.mm:id/", "");
                aid = device.findObject(By.res("com.tencent.mm", id));
                UtilLogs.saveLog("查找文本语音切换控件 id=" + id);
            }

            aid.click();
            UtilLogs.saveLog("点击了文本语音切换控件");

            if (null == edit_bar_txt) {
                aif = device.wait(Until.hasObject(By.res("com.tencent.mm", "aif")), 1000);
                UtilLogs.saveLog("再等待 输入文本框 aif");
            } else {
                String id = edit_bar_txt.replace("com.tencent.mm:id/", "");
                aif = device.wait(Until.hasObject(By.res("com.tencent.mm", id)), 1000);
                UtilLogs.saveLog("再等待 输入文本框 id=" + id);
            }
        }

        UiObject2 object2EditText;
        if (null == edit_bar_txt) {
            object2EditText = device.findObject(By.res("com.tencent.mm", "aif")); // 文本框
            UtilLogs.saveLog("查找 输入文本框  aif");
        } else {
            String id = edit_bar_txt.replace("com.tencent.mm:id/", "");
            object2EditText = device.findObject(By.res("com.tencent.mm", id));
            UtilLogs.saveLog("查找 输入文本框 id=" + id);
        }

        if (null == object2EditText) {
            try {
                UiObject object;
                if (null == edit_bar_txt) {
                    object = device.findObject(new UiSelector().resourceId("com.tencent.mm:id/aif"));
                    UtilLogs.saveLog("再 查找 输入文本框 com.tencent.mm:id/aif");
                } else {
                    object = device.findObject(new UiSelector().resourceId(edit_bar_txt));
                    UtilLogs.saveLog("再 查找 输入文本框 " + edit_bar_txt);
                }

                if (null != object && object.exists()) {
                    object.setText("");
                    object.setText(message);
                    UtilLogs.saveLog("填写回复：" + message);
                }
                Rect rect = object.getBounds();
                int cx;
                int cy;
                if (null == rect) {
                    // [120,1128][505,1192]
                    cx = (505 - 120) / 2;
                    cy = (1192 - 1128) / 2;

                    UtilLogs.saveLog("文本框默认位置：x=" + cx + "，y=" + cy);
                } else {
                    cx = rect.centerX();
                    cy = rect.centerY();
                    UtilLogs.saveLog("文本获取的位置：x=" + cx + "，y=" + cy);
                }
                device.click(cx, cy); // 弹出软键盘，下一步查找"发送"按钮
                UtilLogs.saveLog("文本框点击获取焦点，弹窗软键盘");
            } catch (UiObjectNotFoundException e) {
                e.printStackTrace();
                UtilLogs.saveLog("文本框异常：" + e.getMessage());
            }
        } else {
            object2EditText.setText("");
            object2EditText.setText(message);
            UtilLogs.saveLog("文本框清空，填写：" + message);

            int cx;
            int cy;
            Rect rect = object2EditText.getVisibleBounds();
            if (null == rect) {
                // [120,1128][505,1192]
                cx = (505 - 120) / 2;
                cy = (1192 - 1128) / 2;
                UtilLogs.saveLog("文本框默认位置22：x=" + cx + "，y=" + cy);
            } else {
                cx = rect.centerX();
                cy = rect.centerY();
                UtilLogs.saveLog("文本获取的位置22：x=" + cx + "，y=" + cy);
            }
            device.click(cx, cy); // 弹出软键盘，下一步查找"发送"按钮
            UtilLogs.saveLog("文本框点击获取焦点，弹窗软键盘22");
        }

        device.wait(Until.hasObject(By.text("发送")), 15000); // 发送

        UiObject2 object = device.findObject(By.text("发送")); // 发送
        object.click();
        UtilLogs.saveLog("点击了发送按钮");

        UtilLogs.saveLog("发送的回复入库");
        UtilSQLite.getInstance(context).insertChat(phone, wxid, message, "me"); // chatSayHello

        UiObject2 editText;
        if (null == edit_bar_txt) {
            editText = device.findObject(By.res("com.tencent.mm", "aif")); // 文本框
            UtilLogs.saveLog("重新查找文本框 aif");
        } else {
            String id = edit_bar_txt.replace("com.tencent.mm:id/", "");
            editText = device.findObject(By.res("com.tencent.mm", id));
            UtilLogs.saveLog("重新查找文本框 id=" + id);
        }

        editText.setText("");
        UtilLogs.saveLog("清空文本框");

        if (answerList.size() > 0) {

            device.pressBack(); // 收起软键盘
            UtilLogs.saveLog("收起软键盘");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


            UtilLogs.saveLog("回复下一条");
            chatSayHello(context, device, phone, wxid, answerList, tip);
        }
    }

    /**
     * 查找列表中对方的头像，点击进入详细资料界面，获取其微信号等<br/>
     * 返回上一个界面-聊天界面
     *
     * @param title 好友自己的原始备注名
     * @return 返回资料数组：0-微信号，1-备注名，2-昵称
     */
    public static String[] getFriendAvatar(UiDevice device, String title) {
        UtilLogs.saveLog("查找好友的头像：" + title);

        String[] friendDetails = new String[3];
        friendDetails[0] = "";
        friendDetails[1] = "";
        friendDetails[2] = "";

        UiScrollable listViewObject = new UiScrollable(new UiSelector().className("android.widget.ListView"));

        boolean hasFriendAvatarObject = false;
        UiObject avatarObject = device.findObject(new UiSelector().description(title + "头像")); // 根据描述
        try {
            hasFriendAvatarObject = listViewObject.scrollIntoView(avatarObject);
            UtilLogs.saveLog("查找好友的头像-结果：" + hasFriendAvatarObject);
        } catch (UiObjectNotFoundException e) {
            e.printStackTrace();
            UtilLogs.saveLog("查找好友的头像 Exception：" + e.getMessage());
        }
        listViewObject.waitForExists(5000);

        if (hasFriendAvatarObject) {
            UiObject2 avatarObject2 = device.findObject(By.descContains(title + "头像"));
            UtilLogs.saveLog("查找好友的头像-avatarObject2：==");
            while (!avatarObject2.isClickable()) {
                avatarObject2 = avatarObject2.getParent();
            }
            avatarObject2.click();
            UtilLogs.saveLog("点击了好友的头像-avatarObject2");

            // nextAty，朋友详细信息界面
            UtilLogs.saveLog("nextAty，朋友详细信息界面");

            TestUtilCtrl.showCurrentActivity(device, "是否为'详细资料'");

            friendDetails = TestUtilCtrl.getFriendDetails(device, 1);


        } else { // 有时上面找不到
            List<UiObject2> objects = device.findObjects(By.descContains(title + "头像"));
            UtilLogs.saveLog("再次查找好友的头像-avatar");
            if (objects.size() > 0) {
                hasFriendAvatarObject = true;
                UiObject2 uiObject2 = objects.get(0);
                UtilLogs.saveLog("再次查找好友的头像-avatarObject2----：");
                while (!uiObject2.isClickable()) {
                    uiObject2 = uiObject2.getParent();
                }
                uiObject2.click();
                UtilLogs.saveLog("点击了好友的头像-uiObject2");

                // nextAty，朋友详细信息界面
                UtilLogs.saveLog("nextAty，朋友详细信息界面");

                TestUtilCtrl.showCurrentActivity(device, "是否为'详细资料'");

                friendDetails = TestUtilCtrl.getFriendDetails(device, 1);

            }
        }

        if (hasFriendAvatarObject) {
            UtilLogs.saveLog("最终找到好友的头像-avatar，并拿到了details");
            device.pressBack();
            UtilLogs.saveLog("pressBack 返回聊天页面");
        }

        return friendDetails;
    }

    private static void deleteObject(UiDevice device, UiObject2 object) {
        UtilLogs.saveLog("删除对象：" + (null == object));
        if (null != object) {
            TestUtilCtrl.longClick(device, object);
            UtilLogs.saveLog("长按了控件2");
            Boolean hasDelete = device.wait(Until.hasObject(By.text("删除")), 5000);
            if (hasDelete) {
                UiObject2 deleted = device.findObject(By.text("删除"));
                deleted.click();
                UtilLogs.saveLog("删除了消息");
                return;
            }
        }

        UtilLogs.saveLog("删除失败");
        // todo 7.0.5删除失败
    }
}
